package proxyhelper

import (
	"bufio"
	"fmt"
	"io"
	"iptv_server/v3/src/settings"
	"iptv_server/v3/v2_src/utils"
	"iptv_server/v3/v2_src/utils/common"
	"iptv_server/v3/v2_src/utils/filtersoter"
	"net/http"
	"net/url"
	"strings"
)

func Get_sorted_filter_mapper(c *http.Client, u *url.URL, fallbackPort int, fallbackBasePath string, needSorter, needFilter bool) (sorter common.Sorter, filter common.Filter, mapper common.Mapper) {
	//
	var suffix string
	sorter = filtersoter.NewSorter()
	filter = filtersoter.NewFilter()
	mapper = filtersoter.NewMapper()

	// if needSorter || needFilter {
	// 先转成 string, 进行 deep copy
	u2, err := url.Parse(u.String())
	if err != nil {
		return
	}

	// 外网 没有解析的  sorter, filter ; 换成自己的
	local := fmt.Sprintf("127.0.0.1:%d", settings.SitePort)
	// lan := fmt.Sprintf("server.lan", settings.SitePort)
	if !(strings.Contains(u2.Host, "server.lan") || strings.Contains(u2.Host, local)) {
		u2.Host = local
	}

	if needSorter {
		suffix = ".sorter"
		get(c, u2, fallbackPort, suffix, fallbackBasePath, sorter)
	}

	if needFilter {
		suffix = ".filter"
		get(c, u2, fallbackPort, suffix, fallbackBasePath, filter)
	}

	suffix = ".mapper"
	get(c, u2, fallbackPort, suffix, fallbackBasePath, mapper)

	// }

	// fmt.Printf("sorter.Size(): %v\n", sorter.Size())
	// fmt.Printf("filter: %v\n", filter.Size())
	// return Get_sorter(c, u, fallbackPort, fallbackBasePath), Get_filter(c, u, fallbackPort, fallbackBasePath)
	return
}

func Get_sorter(c *http.Client, u *url.URL, fallbackPort int, fallbackBasePath string) common.Sorter {
	//
	suffix := ".sorter"
	sorter := filtersoter.NewSorter()
	get(c, u, fallbackPort, suffix, fallbackBasePath, sorter)

	return sorter
}

func Get_filter(c *http.Client, u *url.URL, fallbackPort int, fallbackBasePath string) common.Filter {

	suffix := ".filter"
	filter := filtersoter.NewFilter()
	get(c, u, fallbackPort, suffix, fallbackBasePath, filter)

	// fmt.Printf("sorter.Size(): %v\n", sorter.Size())
	// fmt.Printf("filter: %v\n", filter.Size())
	return filter
}

// (h *fallback_redirect2fileServer)
func get_resp(c *http.Client, u *url.URL, suffix string, fallbackPort int, fallbackBasePath string) *http.Response {

	p := u.Path
	rawp := u.RawPath
	defer func() {
		u.Path = p
		u.RawPath = rawp
	}()

	u.Path = u.Path + suffix
	u.RawPath = u.RawPath + suffix
	// fmt.Printf("u2: %v\n", u)
	resp, err := c.Get(u.String())

	if err != nil || resp.StatusCode >= 400 {
		if err == nil {
			resp.Body.Close()
		}

		ps := strings.Split(u.Path, "/")
		name := ps[len(ps)-1]
		if len(name) == 0 {
			if len(ps)-2 > -1 {
				name = ps[len(ps)-2]
			} else {
				name = "my_default" + suffix
			}
		}

		path := fmt.Sprintf("http://127.0.0.1:%d%s/%s", fallbackPort, fallbackBasePath, name)
		// fmt.Printf("path: %v\n", path)
		resp, err = c.Get(path)
		if err != nil {
			return nil
		}
	}
	return resp
}

func get(c *http.Client, u *url.URL, fallbackPort int, suffix string, fallbackBasePath string, putter common.Putter) bool {
	resp := get_resp(c, u, suffix, fallbackPort, fallbackBasePath)
	if resp == nil {
		return false
	}
	defer resp.Body.Close()
	if resp.StatusCode >= 400 {
		utils.Logger.Warnf("GET %s error", suffix)
		return false
	}

	r := bufio.NewReader(resp.Body)
	for {
		if line, err := r.ReadString('\n'); err == nil {
			line = strings.Trim(line, " ,\n\r")
			line = strings.TrimSpace(line)
			if len(line) > 0 {
				putter.Put(line)
				lower := strings.ToLower(line)
				if lower != line {
					putter.Put(lower)
				}
				// fmt.Printf("line: %s :: %v\n", suffix, line)
			}
		} else if err == io.EOF {
			break
		} else {
			return false
		}
	}

	return true
}
